// mCalcServer.h
// author: Dr. Pablo García Bringas <pgb@eside.deusto.es>

#ifndef __MCalcSERVER_H
#define __MCalcSERVER_H

#include <fstream>
#include <iostream>
#include <map>
#include <sstream>

#include "TcpListener.h"
#include "Thread.h"
#include "SQLiteMap.h"
#include "mDNSTypes.h"

using namespace std;

namespace PracticaCaso
{
	class mCalcServer;
	class mDNSObserver: public Thread {
		private:
			int fd4Receiving;
			bool keepRunning;
			struct sockaddr_in addr;
			void run();
			mCalcServer* client;

		public:
			mDNSObserver(mCalcServer* client);
			~mDNSObserver();
			void stop();
	};

	class mDNSQueryWrapper {
		private:
			int fd4Sending;
			struct sockaddr_in addr;
			mCalcServer* client;

		public:
			mDNSQueryWrapper(mCalcServer* client);
			~mDNSQueryWrapper();
			void send (string str);
	};

	class mCalcServer: public TcpListener {
		private:
			string domain, pendingQuery, pendingQueryCode, solvedQuery;
			int randSeed;
			SQLiteMap * sqliteMap;
			map<string, string> dns2IpPortMap;
			bool leerCache, satisfiedQuery;
			void loadMappings(string mappinsFileName);
			string delegateExternalDnsServer(string serverDetails, string dnsName);
			string delegatemDNSCommunity(string dnsName);
			mDNSObserver* observer;
			mDNSQueryWrapper* queryWrapper;
 
		public:
			mCalcServer(int p, string m, bool leerCache);
			mCalcServer(const mCalcServer&);
			mCalcServer & operator = (const mCalcServer &);
			~mCalcServer();
			
				
			string translate(string dnsEntry);
			void mdns_management(string cmd, string payload, string code); 
			void mdns_manage_response(string cmd, string payload, string code); 
			void mdns_manage_request(string cmd, string payload, string code); 
			friend ostream & operator << (ostream &os, mCalcServer &n);
	};

	class mCalcServerThread: public Thread {
		private:
			TcpClient* dnsClient;
			mCalcServer& dnsServer;
			void run();
		public:
			mCalcServerThread(TcpClient* c, mCalcServer& s): dnsClient(c), dnsServer(s) {}
			~mCalcServerThread();
	};
};
#endif
